package circulardht;

/**
 *
 * @author Cem Gulduren
 */

import java.awt.*;

public class CircularDHTSim extends java.applet.Applet {
    
    int startPeer ; // peer that will look for the selected key
    int selectedKey ; // key chosen by the user
    
    public void init() {	// initialization code
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    initComponents(); 
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    // code generated by NetBeans GUI Designer tool
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jComboBox1 = new javax.swing.JComboBox();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jComboBox2 = new javax.swing.JComboBox();
        jButton3 = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();

        jLabel1.setText("jLabel1");

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setForeground(new java.awt.Color(255, 255, 255));

        jLabel2.setText("0");

        jLabel7.setText("3");

        jLabel8.setText("6");

        jLabel9.setText("9");

        jLabel10.setText("12");

        jLabel11.setText("15");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addGap(29, 29, 29)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(56, 56, 56))
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(106, 106, 106)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(130, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel2)
                .addGap(30, 30, 30)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(jLabel11))
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(69, 69, 69)
                        .addComponent(jLabel10))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(77, 77, 77)
                        .addComponent(jLabel8)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 28, Short.MAX_VALUE)
                .addComponent(jLabel9)
                .addGap(92, 92, 92))
        );

        jButton1.setText("Start circular DHT applet");
        jButton1.setMaximumSize(new java.awt.Dimension(100, 100));
        jButton1.setMinimumSize(new java.awt.Dimension(100, 100));
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton1MouseClicked(evt);
            }
        });

        jComboBox1.setVisible(false);
        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0", "3", "6", "9", "12", "15" }));

        jLabel3.setVisible(false);
        jLabel3.setText("Choose origin peer:");

        jLabel4.setVisible(false);
        jLabel4.setText("Search for key:");

        jComboBox2.setVisible(false);
        jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2", "4", "5", "7", "8", "10", "11", "13", "14", "16", "17" }));

        jButton3.setVisible(false);
        jButton3.setText("Search");
        jButton3.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton3MouseClicked(evt);
            }
        });

        jLabel5.setVisible(false);
        jLabel5.setText("Peer X is responsible for key Y");

        jLabel6.setVisible(false);
        jLabel6.setText("Clockwise path from Peer X to Y");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(54, 54, 54)
                        .addComponent(jButton3))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(7, 7, 7)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel3)
                                    .addComponent(jLabel4))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGap(14, 14, 14))))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel6)
                            .addComponent(jLabel5))))
                .addContainerGap(144, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(31, 31, 31)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(50, 50, 50)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel3))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel4)
                            .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addComponent(jButton3)
                        .addGap(27, 27, 27)
                        .addComponent(jLabel5)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel6)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
    }                       

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) { // the "start applet" button                                 
        
    	// the numbers that show the dots are visible from the start because making them visible later on
    	// causes a problem with the drawing of the DHT circle. The issue could not be fixed.
    	
        jButton1.setVisible(false);
        jButton3.setVisible(true);
        jLabel3.setVisible(true);
        jLabel4.setVisible(true);
        jComboBox1.setVisible(true);
        jComboBox2.setVisible(true);
        
        Graphics2D gfx = (Graphics2D) jPanel1.getGraphics();
        
        gfx.setStroke(new BasicStroke(2)); // make the circle thicker
                
        // the calculations needed to draw the circle with six dots (peers) on it
        int a = 256 / 2;
        int b = a;
        int r = a - 256 / 10;
        a = 100;
        b = 100;
        gfx.drawOval(a - r + 10, b - r + 10, 2 * r, 2 * r);
        gfx.setColor(Color.red);
        for (int i = 0; i < 6; i++) {
            double added = Math.PI / 6;
            double t = 2 * Math.PI * i / 6 + added;
            int x = (int) Math.round(a + r * Math.cos(t)) + 10;
            int y = (int) Math.round(b + r * Math.sin(t)) + 10;
            gfx.fillOval(x - 4, y - 4, 8, 8);
    }
    }                                                                            

    private void jButton3MouseClicked(java.awt.event.MouseEvent evt) { // the "search for key" button                                 
        
        String selPeer = (String) jComboBox1.getSelectedItem();
        String selKey = (String) jComboBox2.getSelectedItem();
        
        startPeer = Integer.parseInt(selPeer);
        selectedKey = Integer.parseInt(selKey);
        
        int endPeer = 3; //placeholder value 3
        
        jLabel5.setVisible(true);
        jLabel6.setVisible(true);
        
        if (selectedKey == 1 || selectedKey == 2) { // peer 0 is responsible for keys 1 and 2
            jLabel5.setText("Peer 0 is responsible for Key " + selKey);
            endPeer = 0;
            jLabel6.setText("Clockwise path from Peer " + startPeer + " to " + endPeer); // the label describing the clockwise path
        }
        
        if (selectedKey == 4 || selectedKey == 5) { // peer 3 is responsible for keys 3 and 4
            jLabel5.setText("Peer 3 is responsible for Key " + selKey);
            endPeer = 3;
            jLabel6.setText("Clockwise path from Peer " + startPeer + " to " + endPeer);
        }
        
        if (selectedKey == 7 || selectedKey == 8) {
            jLabel5.setText("Peer 6 is responsible for Key " + selKey);
            endPeer = 6;
            jLabel6.setText("Clockwise path from Peer " + startPeer + " to " + endPeer);
        }
        
        if (selectedKey == 10 || selectedKey == 11) {
            jLabel5.setText("Peer 9 is responsible for Key " + selKey);
            endPeer = 9;
            jLabel6.setText("Clockwise path from Peer " + startPeer + " to " + endPeer);
        }
        
        if (selectedKey == 13 || selectedKey == 14) {
            jLabel5.setText("Peer 12 is responsible for Key " + selKey);
            endPeer = 12;
            jLabel6.setText("Clockwise path from Peer " + startPeer + " to " + endPeer);
        }
        
        if (selectedKey == 16 || selectedKey == 17) {
            jLabel5.setText("Peer 15 is responsible for Key " + selKey);
            endPeer = 15;
            jLabel6.setText("Clockwise path from Peer " + startPeer + " to " + endPeer);
        }
        
        int startAngle = 30 ; // placeholder values for the angles
        int plusAngle = 60;
        
        // there are different starting and ending angles for the arc that's going to show the path through the circle
        // the plusAngle is the angle that will be added to the start angle, thus giving the ending angle
        if (startPeer == 0) {
            
            if (endPeer == 0) {
                startAngle = 0;
                plusAngle = 0;
            }
            
            if (endPeer == 3) {
                startAngle = 30;
                plusAngle = 60;
            }
            
            if (endPeer == 6) {
                startAngle = 330;
                plusAngle = 120;
            }
            
            if (endPeer == 9) {
                startAngle = 270;
                plusAngle = 180;
            }
            
            if (endPeer == 12) {
                startAngle = 210;
                plusAngle = 240;
            }
            
            if (endPeer == 15) {
                startAngle = 150;
                plusAngle = 300;
            }
        }
        
        if (startPeer == 3) {
            if (endPeer == 0) {
                startAngle = 90;
                plusAngle = 300;
            }
            
            if (endPeer == 3) {
                startAngle = 0;
                plusAngle = 0;
            }
            
            if (endPeer == 6) {
                startAngle = 330;
                plusAngle = 60;
            }
            
            if (endPeer == 9) {
                startAngle = 270;
                plusAngle = 120;
            }
            
            if (endPeer == 12) {
                startAngle = 210;
                plusAngle = 180;
            }
            
            if (endPeer == 15) {
                startAngle = 150;
                plusAngle = 240;
            }
        }
        
        if (startPeer == 6) {
            if (endPeer == 0) {
                startAngle = 90;
                plusAngle = 240;
            }
            
            if (endPeer == 3) {
                startAngle = 30;
                plusAngle = 300;
            }
            
            if (endPeer == 6) {
                startAngle = 0;
                plusAngle = 0;
            }
            
            if (endPeer == 9) {
                startAngle = 270;
                plusAngle = 60;
            }
            
            if (endPeer == 12) {
                startAngle = 210;
                plusAngle = 120;
            }
            
            if (endPeer == 15) {
                startAngle = 150;
                plusAngle = 180;
            }
        }
        
        if (startPeer == 9) {
            if (endPeer == 0) {
                startAngle = 90;
                plusAngle = 180;
            }
            
            if (endPeer == 3) {
                startAngle = 30;
                plusAngle = 240;
            }
            
            if (endPeer == 6) {
                startAngle = 330;
                plusAngle = 300;
            }
            
            if (endPeer == 9) {
                startAngle = 0;
                plusAngle = 0;
            }
            
            if (endPeer == 12) {
                startAngle = 210;
                plusAngle = 60;
            }
            
            if (endPeer == 15) {
                startAngle = 150;
                plusAngle = 120;
            }
        }
        
        if (startPeer == 12) {
            if (endPeer == 0) {
                startAngle = 90;
                plusAngle = 120;
            }
            
            if (endPeer == 3) {
                startAngle = 30;
                plusAngle = 180;
            }
            
            if (endPeer == 6) {
                startAngle = 330;
                plusAngle = 240;
            }
            
            if (endPeer == 9) {
                startAngle = 270;
                plusAngle = 300;
            }
            
            if (endPeer == 12) {
                startAngle = 0;
                plusAngle = 0;
            }
            
            if (endPeer == 15) {
                startAngle = 150;
                plusAngle = 60;
            }
        }
        
        if (startPeer == 15) {
            if (endPeer == 0) {
                startAngle = 90;
                plusAngle = 60;
            }
            
            if (endPeer == 3) {
                startAngle = 30;
                plusAngle = 120;
            }
            
            if (endPeer == 6) {
                startAngle = 330;
                plusAngle = 180;
            }
            
            if (endPeer == 9) {
                startAngle = 270;
                plusAngle = 240;
            }
            
            if (endPeer == 12) {
                startAngle = 210;
                plusAngle = 300;
            }
            
            if (endPeer == 15) {
                startAngle = 0;
                plusAngle = 0;
            }
        }
        
        // the redLine is the arc that will be drawn to show the path from the chosen peer to the end peer on the circle
        Graphics2D redLine = (Graphics2D) jPanel1.getGraphics();
        
        redLine.setColor(Color.red);
        
        redLine.setStroke(new BasicStroke(3)); // the arc is thicker than the circle to make it more visible
        
        redLine.drawArc(10, 10, 200, 200, startAngle, plusAngle);
        // drawing the arc
    }                                     

    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton3;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JComboBox jComboBox2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
}